
package sbc.fact;


import corso.lang.CorsoConnection;
import corso.lang.CorsoConstOid;
import corso.lang.CorsoData;
import corso.lang.CorsoDataException;
import corso.lang.CorsoException;
import corso.lang.CorsoShareable;
import corso.lang.CorsoStrategy;
import sbc.repos.*;


public class RawMaterialStream implements CorsoShareable {
    private Module module;
    private CorsoConstOid nextOid;

  /**
   * Constructor
   *
   * @param oid             the first element of the stream
   *
   */
    public RawMaterialStream(CorsoConstOid oid) {
        nextOid = oid;
    }

  /**
   * Method which is called, if you read the structure from an oid
   *
   * @param data            CorsoData object from which the data is read
   *
   * @return                none
   *
   */
    public void read (CorsoData data) throws CorsoDataException {
        StringBuffer structName = new StringBuffer ();

        int arity = data.getStructTag (structName);
        if (arity != 2) {
          System.out.println ("arity = " + arity);
          throw new CorsoDataException ();
        }
        //number = data.getInt ();
        if(structName.toString().equals("Board")) {
            module = new Board();
        } else if(structName.toString().equals("Sensor")) { 
            module = new Sensor();
        } else if(structName.toString().equals("Unit")) { 
            module = new Unit();
        } else {
            System.out.println ("unknown struct: " + structName);
            throw new CorsoDataException ();
        }
        data.getShareable(module);
        nextOid = new CorsoConstOid();
        data.getShareable (nextOid);
     }

  /**
   * Method which is called, if you write the structure to an oid
   *
   * @param data            CorsoData object to which the data is written
   *
   * @return                none
   *
   */
    public void write (CorsoData data) throws CorsoDataException {
        data.putStructTag (module.getType().toString(), 2);
        data.putShareable(module);
        data.putShareable (nextOid);
    }

  /**
   * Method which returns the next value of the stream
   *
   * @param                 none
   *
   * @return                the value which is read out from the oid
   *
   */
    public Module readNextModule() throws CorsoException {
        nextOid.readShareable (this, null, CorsoConnection.INFINITE_TIMEOUT);
        return module;
    }

  /**
   * Method which appends a value to the stream
   *
   * @param newNumber       the number which is appended to the stream
   *
   * @return                none
   *
   */
    public void appendModule(Module mod) {
        CorsoConstOid newOid = null;
        CorsoConstOid currentNextOid = null;
        CorsoConnection connection = nextOid.getConnection ();

        try {
          CorsoStrategy stra = new CorsoStrategy (CorsoStrategy.PR_DEEP_EAGER);
          newOid = connection.createConstOid (stra);
        } catch (CorsoException e2) {
          System.out.println ("Cannot create transaction or oid: " + e2);
          System.exit (-1);
        }

        for (; ; ) {
            module = mod;

            currentNextOid = nextOid;
            nextOid = newOid;

            // write to CORSO ConstOid currentNextOid *******************************
            // if it fails, then it was yet written, so read it out and try it again
            try {
                currentNextOid.writeShareable (this, CorsoConnection.INFINITE_TIMEOUT);
                break;
            } catch (CorsoException e3) {
                try {
                    // if someone has appended new data to stream ***********************
                    currentNextOid.readShareable (this, null, CorsoConnection.INFINITE_TIMEOUT);
                } catch (CorsoException e4) {
                    System.out.println ("Cannot cancel request or read stream: " + e4);
                    System.exit (-1);
                }
            }
        }
        return;
    }
}




